#include <WiFi.h>
#include <ArduinoJson.h>
#include <PubSubClient.h>
#include <WiFiClientSecure.h>

// const char* wifiSsid = "FF&LL_2.4G"; // wifi名
const char *wifiSsid = "unhan-nova7"; // wifi名
const char *wifiPasswd = "12356666";  // wifi密码

// MQTT Broker Settings
const char *mqtt_broker = "b371a1f4.ala.cn-hangzhou.emqxsl.cn";
const char *mqtt_topic = "unhan/esp32";
const char *mqtt_username = "unhan";
const char *mqtt_password = "12345678";
const int mqtt_port = 8883;

const char *ca_cert = R"EOF(
-----BEGIN CERTIFICATE-----
MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh
MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3
d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD
QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT
MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG
9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB
CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97
nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt
43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P
T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4
gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO
BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR
TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw
DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr
hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg
06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF
PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls
YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk
CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4=
-----END CERTIFICATE-----
)EOF";

WiFiClientSecure esp_client;
PubSubClient mqtt_client(esp_client);

DynamicJsonDocument jsonObj(1024);

typedef enum
{
    RGB_LED_1 = 1,
    RGB_LED_2 = 2,
    RGB_LED_3 = 3,
    RGB_LED_4 = 4,
} MQTT_ACTION_TYPE;

const int rgb_min_num = 0;
const int rgb_max_num = 50;
const int rgb_step = 10;

void connectToMQTT();

void mqttCallback(char *mqtt_topic, byte *payload, unsigned int length);

void setup()
{
    Serial.begin(115200);
    delay(1000);
    Serial.println("项目初始化........");

    WiFi.begin(wifiSsid, wifiPasswd);
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.print("wifi status:");
        Serial.println(WiFi.status());
        Serial.println("连接网络中...");
        delay(500);
    }
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());

    esp_client.setCACert(ca_cert);
    mqtt_client.setServer(mqtt_broker, mqtt_port);
    mqtt_client.setKeepAlive(60);
    mqtt_client.setCallback(mqttCallback); // Corrected callback function name

    connectToMQTT();
}

void connectToMQTT()
{
    while (!mqtt_client.connected())
    {
        String client_id = "esp32-client-" + String(WiFi.macAddress());
        Serial.printf("Connecting to MQTT Broker as %s.....\n", client_id.c_str());
        if (mqtt_client.connect(client_id.c_str(), mqtt_username, mqtt_password))
        {
            Serial.println("Connected to MQTT broker");
            mqtt_client.subscribe(mqtt_topic);
            mqtt_client.publish(mqtt_topic, "Hi EMQX I'm ESP32 ^^"); // Publish message upon successful connection
        }
        else
        {
            Serial.print("Failed, rc=");
            Serial.print(mqtt_client.state());
            Serial.println(" try again in 5 seconds");
            delay(5000);
        }
    }
}

void mqttCallback(char *mqtt_topic, byte *payload, unsigned int length)
{
    Serial.print("Message received on mqtt_topic: ");
    Serial.println(mqtt_topic);
    deserializeJson(jsonObj, (char *)payload);

    Serial.print("Message action: ");
    int act = jsonObj["a"];
    Serial.println(act);

    switch (act)
    {
    case RGB_LED_1:
        digitalWrite(RGB_BUILTIN, HIGH);
        break;
    case RGB_LED_2:
        digitalWrite(RGB_BUILTIN, LOW);
        break;
    case RGB_LED_3:
        int r, g, b;
        r = jsonObj["d"]["r"];
        g = jsonObj["d"]["g"];
        b = jsonObj["d"]["b"];
        neopixelWrite(RGB_BUILTIN, r, g, b);
        break;
    case RGB_LED_4:
        digitalWrite(RGB_BUILTIN, LOW);
        delay(100);
        int ri, gi, bi;
        ri, gi, bi = rgb_min_num, rgb_min_num, rgb_min_num;
        Serial.printf("RGB LED r:%d g:%d b:%d \n", ri, gi, bi);
        while (ri <= rgb_max_num)
        {
            while (gi <= rgb_max_num)
            {
                while (bi <= rgb_max_num)
                {
                    Serial.printf("RGB LED r:%d g:%d b:%d \n", ri, gi, bi);
                    neopixelWrite(RGB_BUILTIN, ri, gi, bi);
                    delay(300);
                    bi = bi + rgb_step;
                }
                if (bi >= rgb_max_num)
                {
                    bi = rgb_min_num;
                }
                gi = gi + rgb_step;
            }
            if (gi >= rgb_max_num)
            {
                gi = rgb_min_num;
            }
            if (bi >= rgb_max_num)
            {
                bi = rgb_min_num;
            }
            ri = ri + rgb_step;
        }
        break;
    default:
        break;
    }
}

void loop()
{
    Serial.println("loop runing........\n");
    if (WiFi.status() != WL_CONNECTED)
    {
        Serial.println("WiFI已断开......");
    }

    if (!mqtt_client.connected())
    {
        connectToMQTT();
    }
    mqtt_client.loop();

    delay(1000);
}
